/*
 *
 */

package columnar;

import bitmap.*;
import bufmgr.HashEntryNotFoundException;
import bufmgr.InvalidFrameNumberException;
import bufmgr.PageUnpinnedException;
import bufmgr.ReplacerException;

import com.sun.org.apache.bcel.internal.generic.GOTO;
import global.*;
import heap.Tuple;
import iterator.Iterator;
import java.io.IOException;


public class BitmapIndexScan extends Iterator
{
    private int bitValue;
    private int currentBitmapPositionI;
    private int currentBitmapPositionJ;
    private BitMapFile bm;
    private BitMapHeaderPage header;
    private byte[] tempArray = null;
    private BMPage tempPage;
    private boolean state = false;
    private int position;
    
    public BitmapIndexScan(String file_name)
    {
    	position = 0;
      try {
        bm = new BitMapFile(file_name);
        header = bm.getHeaderPage();
        if (header.get_rootId().pid == -1) // INVALID_PAGE
        {
                System.out.println("The BitMap is Empty!!!");
                Runtime.getRuntime().exit(1);
        }
        currentBitmapPositionI = 0;
        currentBitmapPositionJ = 0;
        tempPage = new BMPage();
        SystemDefs.JavabaseBM.pinPage(header.get_rootId(), tempPage, false/* Rdisk */); // get the page from the DB
        tempArray = tempPage.getBMpageArray(); // get the data array
        SystemDefs.JavabaseBM.unpinPage(header.get_rootId(), false/* not dirty */);
    	SystemDefs.JavabaseBM.flushPage(header.get_rootId());

      } catch (Exception e) {
            System.out.println("The bitmap does not exist, please create bitmap first.");
            Runtime.getRuntime().exit(1);
      }
    }


  /**
   *@return the result tuple
   *@exception JoinsException some join exception
   *@exception IOException I/O errors
   *@exception InvalidTupleSizeException invalid tuple size
   *@exception InvalidTypeException tuple type not valid
   *@exception PageNotReadException exception from lower layer
   *@exception PredEvalException exception from PredEval class
   *@exception UnknowAttrType attribute type unknown
   *@exception FieldNumberOutOfBoundException array out of bounds
   *@exception WrongPermat exception for wrong FldSpec argument
   */
    public Tuple get_next()
    {
        Tuple tuple1 = new Tuple();
        try{
        	do{
        		position++;
                if(state == true)
                    return null;
        		getNext_position(currentBitmapPositionI,currentBitmapPositionJ);
        	}
            while(bitValue != 1);

            Columnarfile.SetOneColumnTupleHeader(tuple1, new AttrType(AttrType.attrInteger));

            tuple1.setIntFld(1, position);

        }catch(Exception e){
            e.printStackTrace();
        }
        return tuple1;
    }
 
    public void close()
    {
        if (!closeFlag)
        {
            try {
				bm.close();
				closeFlag = true;
			} catch (Exception e) {
				e.printStackTrace();
           
			}
        }
    }

    private void getNext_position(int crp_i, int crp_j)
        throws Exception{
        bitValue = 0;

        if(crp_j == 8)
        {
            crp_j = currentBitmapPositionJ = 0;
            crp_i++;
            currentBitmapPositionI++;
        }
        while(crp_i < tempArray.length)
        {
            try
            {
                bitValue = (tempArray[crp_i]>>>crp_j)&1;
                currentBitmapPositionJ++;
            }catch(Exception e)
            {
                e.printStackTrace();
            }
            return;
        }
        
        if (tempPage.getNextPage().pid == 0 || tempPage.getNextPage().pid == -1) {
            state = true;
        }else
        {
            state = false;
            SystemDefs.JavabaseBM.pinPage(tempPage.getNextPage(), tempPage, false/* Rdisk */); // get the page from the DB
            
            tempArray = tempPage.getBMpageArray(); // get the data array
            SystemDefs.JavabaseBM.unpinPage(tempPage.getCurPage(), false/* not dirty */);
        	SystemDefs.JavabaseBM.flushPage(tempPage.getCurPage());
            currentBitmapPositionI = 0;
            currentBitmapPositionJ = 0;
        }
    }
}